// ~ Package Declaration
// ==================================================

package com.wms.data.dao.jdbc.core;

import com.wms.data.PaginateModel;
import com.wms.data.dao.jdbc.DatabaseType;
import com.wms.data.pojo.Pojo;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;


// ~ Comments
// ==================================================

/**
 * 
 * 继承 {@link org.springframework.jdbc.core.simple.SimpleJdbcTemplate} 用以实现分页查询.
 * 
 * <pre>
 * 历史纪录�?
 * 2010-2-10 Timothy
 * 	新建文件
 * </pre>
 * 
 * @author <pre>
 * SD
 * 	Timothy
 * PG
 * 
 * UT
 * 
 * MA
 * </pre>
 * @version $Rev$
 * 
 *          <p/>
 *          $Id$
 * 
 */
public class SimpleJdbcTemplate extends org.springframework.jdbc.core.simple.SimpleJdbcTemplate implements
		SimpleJdbcOperations {

	// ~ Static Fields
	// ==================================================

	// ~ Fields
	// ==================================================

	// ~ Constructors
	// ==================================================

	public SimpleJdbcTemplate(DataSource dataSource) {

		super(dataSource);
	}

	// ~ Methods
	// ==================================================

	public <T> List<T> query(String sql, ParameterizedRowMapper<T> rm, List<?> args) throws DataAccessException {

		return super.query(sql, rm, args.toArray());
	}

	public int queryForInt(String sql, List<?> args) throws DataAccessException {

		return super.queryForInt(sql, args.toArray());
	}

	public List<Map<String, Object>> queryForList(String sql, List<?> args) throws DataAccessException {

		return super.queryForList(sql, args.toArray());
	}

	public long queryForLong(String sql, List<?> args) throws DataAccessException {

		return super.queryForLong(sql, args.toArray());
	}

	public Map<String, Object> queryForMap(String sql, List<?> args) throws DataAccessException {

		return super.queryForMap(sql, args.toArray());
	}

	public <T> T queryForObject(String sql, Class<T> requiredType, List<?> args) throws DataAccessException {

		return super.queryForObject(sql, requiredType, args.toArray());
	}

	public <T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, List<?> args) throws DataAccessException {

		return super.queryForObject(sql, rm, args.toArray());
	}

	public <T extends Pojo<PK>, PK extends Serializable, BP extends Pojo<BPK>, BPK extends Serializable> T queryForObject(String sql,
																																																												ParameterizedRowMapper<T> rm,
																																																												BP args)
		throws DataAccessException {

		return super.queryForObject(sql, rm, new BeanPropertySqlParameterSource(args));
	}

	public int update(String sql, List<?> args) throws DataAccessException {

		return super.update(sql, args.toArray());
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> query(	String sql,
														PaginateModel paginateModel,
														DatabaseType databaseType,
														ParameterizedRowMapper<T> rm,
														Map args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.query(databaseType.generatePaginateSql(sql, paginateModel), rm, args);
	}

	public <T> List<T> query(	String sql,
														PaginateModel paginateModel,
														DatabaseType databaseType,
														ParameterizedRowMapper<T> rm,
														List<?> args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.query(databaseType.generatePaginateSql(sql, paginateModel), rm, args);
	}

	public <T> List<T> query(	String sql,
								PaginateModel paginateModel,
								DatabaseType databaseType,
								ParameterizedRowMapper<T> rm,
								Object... args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));
		
		return this.query(databaseType.generatePaginateSql(sql, paginateModel), rm, args);
	}

	public <T> List<T> query(	String sql,
								PaginateModel paginateModel,
								DatabaseType databaseType,
								ParameterizedRowMapper<T> rm,
								SqlParameterSource args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.query(databaseType.generatePaginateSql(sql, paginateModel), rm, args);
	}

	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> queryForList(String sql,
												PaginateModel paginateModel,
												DatabaseType databaseType,
												Map args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.queryForList(databaseType.generatePaginateSql(sql, paginateModel), args);
	}

	public List<Map<String, Object>> queryForList(String sql,
												PaginateModel paginateModel,
												DatabaseType databaseType,
												List<?> args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.queryForList(databaseType.generatePaginateSql(sql, paginateModel), args);
	}

	public List<Map<String, Object>> queryForList(String sql,
												PaginateModel paginateModel,
												DatabaseType databaseType,
												Object... args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.queryForList(databaseType.generatePaginateSql(sql, paginateModel), args);
	}

	public List<Map<String, Object>> queryForList(String sql,
												PaginateModel paginateModel,
												DatabaseType databaseType,
												SqlParameterSource args) throws DataAccessException {

		String countSql = databaseType.generateCountSql(sql);
		paginateModel.setTotalSize(this.queryForInt(countSql, args));

		return this.queryForList(databaseType.generatePaginateSql(sql, paginateModel), args);
	}

	// 添加直接使用pojo做为sql parameters 参数的设�?
	public <T extends Pojo<PK>, PK extends Serializable, BP extends Pojo<BPK>, BPK extends Serializable> List<T> query(	String sql,
																																																											ParameterizedRowMapper<T> rm,
																																																											BP args)
		throws DataAccessException {

		return super.query(sql, rm, new BeanPropertySqlParameterSource(args));
	}

	public <BP extends Pojo<BPK>, BPK extends Serializable> int queryForInt(String sql, BP args)
		throws DataAccessException {

		return super.queryForInt(sql, new BeanPropertySqlParameterSource(args));
	}

	public <BP extends Pojo<BPK>, BPK extends Serializable> List<Map<String, Object>> queryForList(String sql, BP args)
		throws DataAccessException {

		return super.queryForList(sql, new BeanPropertySqlParameterSource(args));
	}

	public <BP extends Pojo<BPK>, BPK extends Serializable> long queryForLong(String sql, BP args)
		throws DataAccessException {

		return super.queryForLong(sql, new BeanPropertySqlParameterSource(args));
	}

	public <BP extends Pojo<BPK>, BPK extends Serializable> Map<String, Object> queryForMap(String sql, BP args)
		throws DataAccessException {

		return super.queryForMap(sql, new BeanPropertySqlParameterSource(args));
	}

	public <T extends Pojo<PK>, PK extends Serializable, BP extends Pojo<BPK>, BPK extends Serializable> T queryForObject(String sql,
																																																												Class<T> requiredType,
																																																												BP args)
		throws DataAccessException {

		return super.queryForObject(sql, requiredType, new BeanPropertySqlParameterSource(args));
	}

	public <BP extends Pojo<BPK>, BPK extends Serializable> int update(String sql, BP args) throws DataAccessException {

		return super.update(sql, new BeanPropertySqlParameterSource(args));
	}

	public <T extends Pojo<PK>, PK extends Serializable, BP extends Pojo<BPK>, BPK extends Serializable> List<T> query(	String sql,
																																																											PaginateModel paginateModel,
																																																											DatabaseType databaseType,
																																																											ParameterizedRowMapper<T> rm,
																																																											BP args)
		throws DataAccessException {

		return this.query(sql, paginateModel, databaseType, rm, new BeanPropertySqlParameterSource(args));
	}

	public <BP extends Pojo<BPK>, BPK extends Serializable> List<Map<String, Object>> queryForList(	String sql,
																																																	PaginateModel paginateModel,
																																																	DatabaseType databaseType,
																																																	BP args)
		throws DataAccessException {

		return this.queryForList(sql, paginateModel, databaseType, new BeanPropertySqlParameterSource(args));
	}

}
